/**
 * @file app_flash_config.c
 * @brief 应用层Flash配置参数管理实现文件
 * @author Claude Code
 * @date 2025-08-09
 * @note 基于drv_flash驱动层，提供业务相关的参数管理功能
 */

#include "app_flash_config.h"
#include <string.h>

/* ================= 私有变量 ================= */

/** @brief 模块初始化标志 */
static bool s_app_flash_config_initialized = false;

/* ================= 私有函数声明 ================= */

/**
 * @brief 转换drv层状态到app层状态
 * @param drv_status drv层状态
 * @retval app层对应状态
 */
static app_flash_status_t convert_drv_status(drv_flash_status_t drv_status);

/* ================= 公共函数实现 ================= */

/**
 * @brief 初始化Flash配置模块
 */
app_flash_status_t app_flash_config_init(void)
{
    drv_flash_status_t drv_status = drv_flash_init();
    if (drv_status != DRV_FLASH_OK) {
        return convert_drv_status(drv_status);
    }
    
    s_app_flash_config_initialized = true;
    return APP_FLASH_OK;
}

/**
 * @brief 读取用户参数
 */
app_flash_status_t app_flash_read_user_params(app_flash_user_params_t* params)
{
    if (!params || !s_app_flash_config_initialized) {
        return APP_FLASH_ERROR_PARAM;
    }

    // 从Flash读取数据
    drv_flash_status_t drv_status = drv_flash_read(APP_FLASH_USER_PAGE_ADDR, 
                                                   params, 
                                                   sizeof(app_flash_user_params_t));
    if (drv_status != DRV_FLASH_OK) {
        // 读取失败，加载默认值
        app_flash_get_default_params(params);
        return convert_drv_status(drv_status);
    }
    
    // 验证数据有效性
    if (!app_flash_is_params_valid(params)) {
        // 数据无效，加载默认值
        app_flash_get_default_params(params);
        return APP_FLASH_ERROR_INVALID;
    }
    
    // 验证CRC
    uint16_t calc_crc = app_flash_calc_params_crc(params);
    if (calc_crc != params->crc16) {
        // CRC错误，加载默认值
        app_flash_get_default_params(params);
        return APP_FLASH_ERROR_CRC;
    }
    
    return APP_FLASH_OK;
}

/**
 * @brief 写入用户参数
 */
app_flash_status_t app_flash_write_user_params(const app_flash_user_params_t* params)
{
    if (!params || !s_app_flash_config_initialized) {
        return APP_FLASH_ERROR_PARAM;
    }
    
    // 创建写入缓冲区并填充数据
    app_flash_user_params_t write_params;
    memcpy(&write_params, params, sizeof(app_flash_user_params_t));
    
    // 设置有效标志和版本
    write_params.valid_flag = APP_FLASH_VALID_FLAG;
    write_params.version = APP_FLASH_DATA_VERSION;
    
    // 计算并设置CRC
    write_params.crc16 = app_flash_calc_params_crc(&write_params);
    
    // 获取页起始地址
    uint32_t page_addr = drv_flash_get_page_addr(APP_FLASH_USER_PAGE_ADDR);
    
    // 擦除页
    drv_flash_status_t drv_status = drv_flash_erase_pages(page_addr, 1);
    if (drv_status != DRV_FLASH_OK) {
        return convert_drv_status(drv_status);
    }
    
    // 写入数据
    drv_status = drv_flash_write(APP_FLASH_USER_PAGE_ADDR, 
                                 &write_params, 
                                 sizeof(app_flash_user_params_t));
    if (drv_status != DRV_FLASH_OK) {
        return convert_drv_status(drv_status);
    }
    
    // 验证写入结果
    app_flash_user_params_t verify_params;
    app_flash_status_t verify_status = app_flash_read_user_params(&verify_params);
    if (verify_status != APP_FLASH_OK) {
        return APP_FLASH_ERROR;
    }
    
    // 比较关键字段
    if (verify_params.solenoid_hit_duration_yany != write_params.solenoid_hit_duration_yany ||
        verify_params.solenoid_hit_duration_ruoy != write_params.solenoid_hit_duration_ruoy) {
        return APP_FLASH_ERROR;
    }
    
    return APP_FLASH_OK;
}

/**
 * @brief 恢复默认参数并写入Flash
 */
app_flash_status_t app_flash_restore_defaults(void)
{
    app_flash_user_params_t default_params;
    app_flash_get_default_params(&default_params);
    return app_flash_write_user_params(&default_params);
}

/**
 * @brief 获取默认参数
 */
void app_flash_get_default_params(app_flash_user_params_t* params)
{
    if (!params) {
        return;
    }
    
    memset(params, 0, sizeof(app_flash_user_params_t));
    
    params->valid_flag = APP_FLASH_VALID_FLAG;
    params->version = APP_FLASH_DATA_VERSION;
    params->solenoid_hit_duration_yany = APP_FLASH_DEFAULT_YANY_HIT_DURATION;
    params->solenoid_hit_duration_ruoy = APP_FLASH_DEFAULT_RUOY_HIT_DURATION;
    
    // 计算CRC
    params->crc16 = app_flash_calc_params_crc(params);
}

/**
 * @brief 检查参数有效性
 */
bool app_flash_is_params_valid(const app_flash_user_params_t* params)
{
    if (!params) {
        return false;
    }
    
    // 检查有效标志
    if (params->valid_flag != APP_FLASH_VALID_FLAG) {
        return false;
    }
    
    // 检查版本（支持向后兼容）
    if (params->version == 0x00 || params->version > APP_FLASH_DATA_VERSION) {
        return false;
    }
    
    // 检查参数范围
    if (params->solenoid_hit_duration_yany > 127 || 
        params->solenoid_hit_duration_ruoy > 127) {
        return false;
    }
    
    return true;
}

/**
 * @brief 计算参数CRC16
 */
uint16_t app_flash_calc_params_crc(const app_flash_user_params_t* params)
{
    if (!params) {
        return 0;
    }
    
    // 计算CRC时排除CRC字段本身
    uint32_t calc_size = sizeof(app_flash_user_params_t) - sizeof(params->crc16);
    return drv_flash_calc_crc16(params, calc_size, 0); // 0表示使用默认多项式
}

/* ================= 便利函数实现 ================= */

/**
 * @brief 快速设置电磁铁打击时间
 */
app_flash_status_t app_flash_set_solenoid_durations(uint8_t yany_duration, uint8_t ruoy_duration)
{
    // 参数范围检查
    if (yany_duration > 127 || ruoy_duration > 127) {
        return APP_FLASH_ERROR_PARAM;
    }
    
    app_flash_user_params_t params;
    
    // 读取当前参数
    app_flash_status_t status = app_flash_read_user_params(&params);
    if (status != APP_FLASH_OK && status != APP_FLASH_ERROR_INVALID && status != APP_FLASH_ERROR_CRC) {
        // 读取失败且不是数据问题，返回错误
        return status;
    }
    
    // 更新打击时间
    params.solenoid_hit_duration_yany = yany_duration;
    params.solenoid_hit_duration_ruoy = ruoy_duration;
    
    // 写入Flash
    return app_flash_write_user_params(&params);
}

/**
 * @brief 快速获取电磁铁打击时间
 */
app_flash_status_t app_flash_get_solenoid_durations(uint8_t* yany_duration, uint8_t* ruoy_duration)
{
    if (!yany_duration || !ruoy_duration) {
        return APP_FLASH_ERROR_PARAM;
    }
    
    app_flash_user_params_t params;
    app_flash_status_t status = app_flash_read_user_params(&params);
    
    // 无论读取成功或失败，都返回参数值（失败时为默认值）
    *yany_duration = params.solenoid_hit_duration_yany;
    *ruoy_duration = params.solenoid_hit_duration_ruoy;
    
    return status;
}

/* ================= 私有函数实现 ================= */

/**
 * @brief 转换drv层状态到app层状态
 */
static app_flash_status_t convert_drv_status(drv_flash_status_t drv_status)
{
    switch (drv_status) {
        case DRV_FLASH_OK:
            return APP_FLASH_OK;
        case DRV_FLASH_ERROR_PARAM:
            return APP_FLASH_ERROR_PARAM;
        default:
            return APP_FLASH_ERROR;
    }
}
